package com.pgytesting.secondhandcar.vo;


import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;

import com.google.gson.Gson;
import com.pgytesting.secondhandcar.util.UrlFilter;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

/**
 * @version v1.0
 * @ProjectName: informationEntry
 * @ClassName: LogAspect
 * @Description: TODO(注解类实现)
 * @Author: sunbo@pgytesting.cn
 * @Date: 2019/4/9 21:38
 */
@Slf4j
@Aspect
@Order(100)
@Component
public class LogAspectAop {
    public static final String DATE_FORMAT = "yyyy:MM:dd HH:mm:ss";

    //execution the scan of pakage 切点package

    @Pointcut("execution( * com.pgytesting.secondhandcar.controller..*(..))")
    public void serviceLog() {

    }

    @Around("serviceLog()")
    public Object around(ProceedingJoinPoint joinPoint) {
        // ProceedingJoinPoint 为JoinPoint 的子类，在父类基础上多了proceed()方法，用于增强切面
        try {
            //获取方法签名
//            MethodSignature signature = (MethodSignature) joinPoint.getSignature();

            Object[] obj = joinPoint.getArgs();
            Object[] objo = obj.clone();
//            Object[] objects = new Object[objo.length];
            for (int i = 0; i < objo.length; i++) {
                if (objo[i] instanceof HttpSession) {
                    objo[i] = "HttpSession";
                } else if (objo[i] instanceof HttpServletRequest) {
                    objo[i] = "HttpServletRequest";
                } else if (objo[i] instanceof HttpServletResponse) {
                    objo[i] = "HttpServletResponse";
                }
//                Class dataClass = objo[i].getClass();
//                Field[] fieldArr = dataClass.getDeclaredFields();
//                Map<String, Object> map = new HashMap();
//                for (int j = 0; j < fieldArr.length; j++) {
//                    Field field = fieldArr[j];
//                    field.setAccessible(true);
//                    Object value;
//					value = field.get(objo[i]);
//                    if (value != null) {
//                        map.put(field.getName(), value);
//                    }
//                }
//                objects[i] = map;
            }

            String url = "";
            // 获取请求地址,此处为内部请求时会出现空指针异常
            RequestAttributes ra = RequestContextHolder.getRequestAttributes();
            ServletRequestAttributes sra = (ServletRequestAttributes) ra;
            HttpServletRequest request;
            if (sra != null) {
                request = sra.getRequest();
                url = "接口：\"" + request.getRequestURI() + "\"";
            }

            String params = new Gson().toJson(objo);
//            JSONObject.toJSONStringWithDateFormat(objects, DATE_FORMAT, SerializerFeature.WriteMapNullValue);
            // 对登录接口进行不打印请求参数过滤
            if (UrlFilter.logUrlFilter(url)) {
                log.info("\n开始调用--> {} 参数:{}", url, params);
            } else {
                log.info("\n开始调用--> {}", url);
            }
            long start = System.currentTimeMillis();
            //如果类名上和方法上都没有Log注解，则直接执行 proceed()
            Object result = joinPoint.proceed();
            long timeConsuming = System.currentTimeMillis() - start;

            if (UrlFilter.logUrlFilter(url)) {
                log.info("\n调用结束<-- {} 返回值:{} 耗时:{}ms",
                        url,
                        new Gson().toJson(result),
                        timeConsuming
                );
            } else {
                log.info("\n调用结束<-- {} 返回值:{} 耗时:{}ms",
                        url,
                        new Gson().toJson(result),
                        timeConsuming
                );
            }
            return result;
        } catch (Throwable throwable) {
            log.error(throwable.getMessage(), throwable);
        }
        return null;
    }

}
